home *** CD-ROM | disk | FTP | other *** search
/ Joystick Magazine 1996 May / cd joy 71No13.iso / pc / demos / eurosoc / source / network.c < prev    next >
C/C++ Source or Header  |  1995-09-21  |  39KB  |  2,034 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <conio.h>
  5. #include <math.h>
  6. #include <time.h>
  7. #include "c:\netnow\hmistd.h"
  8. #include "c:\netnow\netnow.h"
  9. #include "c:\netnow\vdata.h"
  10. #include "c:\netnow\vchat.h"
  11. #include "c:\sos\include\sosm.h"
  12. #include "network.h"
  13. #include "defines.h"
  14. #include "mouse.h"
  15.  
  16. //#include <iostream.h>
  17. //#include <dos.h>
  18.  
  19. unsigned char machine_no;
  20.  
  21. // Player vars
  22.  
  23. volatile int Team_A,Team_B;
  24. volatile int Teams[MAX_NET_USERS],Players[MAX_NET_USERS];
  25. int TeamChoice,PlayerChoice;
  26.  
  27.  
  28. //    General vars
  29.  
  30. char old_mf;
  31. int netsetup_on;        // In network setup
  32. int network_on;        // Network on flag / No of network players
  33. int onetwork_on;
  34. short    wConsoleNode;    // Network ID for machine
  35. short master;            // Network ID for master
  36. volatile int active_nodes;
  37. volatile int net_quit;
  38. int num_of_users=0;
  39.  
  40.  
  41. // Packet types
  42.  
  43. packet_header        in_header;
  44. packet_header        p_header;
  45. packet_data            p_data;
  46. packet_seed            test_seed;
  47. packet_single        test_single;
  48. packet_multiple    test_multiple;
  49.  
  50. //volatile    packet_multiple copy_multiple[512];
  51. volatile    int writeptr;
  52. volatile    int readptr;
  53.  
  54. volatile packet_single user_inp;                // Temp input data
  55.  
  56.  
  57. // Internal network vars
  58.  
  59. _NETNOW_NODE_ADDR address[MAX_NET_USERS];    // Station addresses that we know about.
  60. _NETNOW_NODE_ADDR laddress;                 // Local machines address
  61. volatile    int net_players[16];
  62. volatile int start_multiple; // No of players master has sent to
  63. volatile    int received_seed;  //
  64. volatile    int frame_number;
  65. volatile int slave_pause=FALSE;
  66. volatile    int NetDone;
  67.  
  68.  
  69. // Timer vars
  70.  
  71. volatile int count;
  72. volatile int tick;
  73. volatile int ftick;
  74. int game_speed;
  75.  
  76. // Richards
  77. volatile int hold_loop;
  78.  
  79. // User input arrays
  80.  
  81. struct user_config{
  82.     short type;
  83.     short control;
  84.     int inp_x;
  85.     int inp_y;
  86.     int inp_ox;
  87.     int inp_oy;
  88.     short inp_fb;
  89.     char chng;
  90.     signed char plr;
  91.     };
  92.  
  93. volatile struct user_config users[MAX_NET_USERS];
  94.  
  95. struct user_vectors_i{
  96.     short x_f1;
  97.     short y_f2;
  98.     };
  99.  
  100. volatile struct user_vectors_i users_dir_i[512][MAX_NET_USERS];
  101.  
  102. int icth,isth;            // viewing angle in integers
  103.  
  104.  
  105. // Vars taken from Andy's code (mostly input stuff)
  106.  
  107. volatile char paused;
  108. volatile char pause_request;
  109. volatile char keys[256];
  110. volatile char key_togs[256];
  111.  
  112. signed char key1[6];
  113. signed char key2[6];
  114.  
  115. unsigned short joy1_cnt_x,joy1_cnt_y;
  116. unsigned short joy2_cnt_x,joy2_cnt_y;
  117.  
  118. int joy1_max_x,joy1_max_y,joy1_min_x,joy1_min_y;
  119. int joy2_max_x,joy2_max_y,joy2_min_x,joy2_min_y;
  120.  
  121. volatile int joy1_x=0;
  122. volatile int joy1_y=0;
  123. volatile int joy1_fire=0;
  124.  
  125. volatile int joy2_x=0;
  126. volatile int joy2_y=0;
  127. volatile int joy2_fire=0;
  128.  
  129. volatile char joy1_move=0;
  130. volatile char joy2_move=0;
  131.  
  132. char joystick1_on=FALSE;
  133. char joystick2_on=FALSE;
  134.  
  135. char digital_joy1=FALSE;
  136. char digital_joy2=FALSE;
  137.  
  138. struct joy_struct {
  139.     int FireA1,FireA2,JoyAX,JoyAY;
  140.     int FireB1,FireB2,JoyBX,JoyBY;
  141. };
  142.  
  143. /*
  144. struct rjoy_struct {
  145.     unsigned short x1;
  146.     unsigned short y1;
  147.     unsigned short x2;
  148.     unsigned short y2;
  149.     unsigned short sw;
  150. };
  151.     
  152. volatile struct rjoy_struct rjoy_pos;
  153. */
  154.  
  155. volatile struct joy_struct joy_pos;
  156.  
  157. unsigned short dead_zone=25;            // percentage
  158.  
  159. volatile int ux1,ux2,wptr,rptr;
  160.  
  161. /********************/
  162. /*  INPUT ROUTINES  */
  163. /********************/
  164.  
  165.  
  166. /////////////////
  167. //  JOYSTICKS  //
  168.  
  169. //Function to gather joystick data and return in a joystick structure
  170.  
  171. int    x1ok=1;    // These values indicate whether the axes are connected or not...
  172. int    y1ok=2;    // for calibration they should be initialised.
  173. int    x2ok=4;
  174. int    y2ok=8;    
  175. int    bitaccept=15; // Above values OR'ed
  176.  
  177. #define JOY_TIMEOUT 65535
  178.  
  179. extern void __far JoyRead3(void *);
  180. extern void __far JoyRead2(void *);
  181. extern void __far JoyRead1(void *);
  182.  
  183.  
  184. /******************************************************************************
  185. ******************************************************************************/
  186.  
  187. /*
  188. void    ConvJoys()
  189. {
  190.     joy_pos.FireA1=!((rjoy_pos.sw>>4)&1);
  191.     joy_pos.FireA2=!((rjoy_pos.sw>>5)&1);
  192.     joy_pos.FireB1=!((rjoy_pos.sw>>6)&1);
  193.     joy_pos.FireB2=!((rjoy_pos.sw>>7)&1);
  194.     joy_pos.JoyAX=rjoy_pos.x1;
  195.     joy_pos.JoyAY=rjoy_pos.y1;
  196.     joy_pos.JoyBX=rjoy_pos.x2;
  197.     joy_pos.JoyBY=rjoy_pos.y2;
  198. }
  199. */
  200.  
  201. /******************************************************************************
  202. ******************************************************************************/
  203. /*
  204. void    ReadJoys()
  205. {
  206.     if (joystick1_on && joystick2_on)
  207. // Two joysticks plugged in...
  208.     {
  209.         JoyRead3(&rjoy_pos);
  210.         ConvJoys();
  211.     }
  212.     else
  213.     {
  214.         if (joystick1_on)
  215. // Port 1 joystick only...
  216.         {
  217.             JoyRead1(&rjoy_pos);
  218.             ConvJoys();
  219.         }
  220.         else
  221. // Port 2 joystick only...
  222.         {
  223.             if (joystick2_on)
  224.             {
  225.                 JoyRead2(&rjoy_pos);
  226.                 ConvJoys();
  227.             }
  228.         }
  229.     }
  230. }
  231. */
  232.  
  233. void    ReadJoys(struct joy_struct *JoyData)
  234.     {
  235.     //read joysticks for calibration - always returns!
  236.     int XJA=-1,YJA=-1,XJB=-1,YJB=-1,Fire,FireA,FireB,j;
  237.     int timecount=0;
  238.     int x1read,y1read,x2read,y2read;
  239.     Fire=((int)inp(0x201) ^ 255)>>4;
  240.     FireA=Fire & 3;
  241.     FireB=(Fire>>2) & 3;
  242.  
  243.     JoyData->FireA1=FireA & 1;
  244.     JoyData->FireA2=FireA>>1;
  245.     JoyData->FireB1=FireB & 1;
  246.     JoyData->FireB2=FireB>>1;
  247.  
  248.     XJA=0;
  249.     YJA=0;
  250.     XJB=0;
  251.     YJB=0;
  252.  
  253.     _disable();
  254.     outp(0x201,255);    //Request a reading from the joystick port
  255.  
  256.     x1read=x1ok;
  257.     y1read=y1ok;
  258.     x2read=x2ok;
  259.     y2read=y2ok;
  260.     do
  261.         {
  262.         j=(int)inp(0x201);  //read the current port status
  263.  
  264.         if (x1ok)
  265.             if (x1read=(j & 1)) XJA++;   //increase X counter
  266.         if (y1ok)
  267.             if (y1read=(j & 2)) YJA++;   //increase Y counter
  268.         if (x2ok)
  269.             if (x2read=(j & 4)) XJB++;   //increase X counter
  270.         if (y2ok)
  271.             if (y2read=(j & 8)) YJB++;   //increase Y counter
  272.  
  273.         timecount++;
  274.  
  275.         }
  276.     while((j & bitaccept) && timecount<JOY_TIMEOUT);        //this will cause time out during calibration if not connected!
  277.     _enable();
  278.  
  279.     if (!x1read)
  280.         JoyData->JoyAX=XJA;
  281.     else
  282.         {
  283.         JoyData->JoyAX=0;
  284.         x1ok=0;                                                                //timed out - stop reading!
  285.         bitaccept=x1ok | y1ok | x2ok | y2ok;
  286.         }
  287.  
  288.     if (!y1read)
  289.         JoyData->JoyAY=YJA;
  290.     else
  291.         {
  292.         JoyData->JoyAY=0;
  293.         y1ok=0;
  294.         bitaccept=x1ok | y1ok | x2ok | y2ok;
  295.         }
  296.  
  297.     if (!x2read)
  298.         JoyData->JoyBX=XJB;
  299.     else
  300.         {
  301.         JoyData->JoyBX=0;
  302.         x2ok=0;
  303.         bitaccept=x1ok | y1ok | x2ok | y2ok;
  304.         }
  305.  
  306.     if (!y2read)
  307.         JoyData->JoyBY=YJB;
  308.     else
  309.         {
  310.         JoyData->JoyBY=0;
  311.         y2ok=0;
  312.         bitaccept=x1ok | y1ok | x2ok | y2ok;
  313.         }
  314.     }
  315.  
  316. void read_joy1(unsigned short *x, unsigned short *y, unsigned char *sw)
  317. {
  318.     *x=joy_pos.JoyAX;
  319.     *y=joy_pos.JoyAY;
  320.     *sw=joy_pos.FireA1|(joy_pos.FireA2<<1);
  321. }
  322.  
  323. void read_joy2(unsigned short *x, unsigned short *y, unsigned char *sw)
  324. {
  325.     *x=joy_pos.JoyBX;
  326.     *y=joy_pos.JoyBY;
  327.     *sw=joy_pos.FireB1|(joy_pos.FireB2<<1);
  328. }
  329.  
  330. void read_joystick(char j, unsigned short *x, unsigned short *y, unsigned char *sw)
  331. {
  332.     ReadJoys(&joy_pos);
  333.     if (!j)
  334.         read_joy1(x,y,sw);
  335.     else
  336.         read_joy2(x,y,sw);
  337. }
  338.  
  339. void get_joy_max_min(char j)
  340. {
  341.     int i;
  342.     unsigned    short x,y;
  343.     unsigned char butt;
  344.     unsigned short max_x=0;
  345.     unsigned short min_x=65535;
  346.     unsigned short max_y=0;
  347.     unsigned short min_y=65535;
  348.     do
  349.     {
  350.         read_joystick(j,&x,&y,&butt);
  351.         if (x>max_x)
  352.             max_x=x;
  353.         if (x<min_x)
  354.             min_x=x;
  355.         if (y>max_y)
  356.             max_y=y;
  357.         if (y<min_y)
  358.             min_y=y;
  359.  
  360. // STRANGE????  Need this software loop to get normal range values from joystick!
  361. // Shrug....
  362.     for (i=0; i<200000; i++)
  363.     {
  364.         i+=1;
  365.         i-=1;
  366.     }
  367.  
  368.     }while(!(butt&3));
  369.  
  370.     if (!j)
  371.     {
  372.         joy1_max_x=max_x;
  373.         joy1_max_y=max_y;
  374.         joy1_min_x=min_x;
  375.         joy1_min_y=min_y;
  376.     }
  377.     else
  378.     {
  379.         joy2_max_x=max_x;
  380.         joy2_max_y=max_y;
  381.         joy2_min_x=min_x;
  382.         joy2_min_y=min_y;
  383.     }
  384. }
  385.  
  386. void calibrate_joy(char j,unsigned short *x,unsigned short *y)
  387. {
  388.     unsigned short left,right,up,down;
  389.     unsigned char butt;
  390.     unsigned short max_x,min_x,max_y,min_y;
  391.     float dead_zone=0.6;            // 33% dead_zone!
  392.     char str[40];
  393.     printf("\nPlease circle joystick %d now...\n",j+1);
  394.     get_joy_max_min(j);
  395.  
  396.     if (!j)
  397.     {
  398.         left=joy1_min_x;
  399.         right=joy1_max_x;
  400.         up=joy1_min_y;
  401.         down=joy1_max_y;
  402.     }
  403.     else
  404.     {
  405.         left=joy2_min_x;
  406.         right=joy2_max_x;
  407.         up=joy2_min_y;
  408.         down=joy2_max_y;
  409.     }
  410.  
  411.     printf("Left %d\n",left);
  412.     printf("Right %d\n",right);
  413.     printf("Up %d\n",up);
  414.     printf("Down %d\n",down);
  415.  
  416.     printf("\nNow centre joystick %d and press fire...\n",j+1);
  417.  
  418.     if (!j)
  419.     {
  420.         do
  421.         {
  422.             read_joystick(0,x,y,&butt);
  423.         }while(butt&3);
  424.  
  425.         do
  426.         {
  427.             read_joystick(0,x,y,&butt);
  428.         }while(!(butt&3));
  429.     }
  430.     else
  431.     {
  432.         do
  433.         {
  434.             read_joystick(1,x,y,&butt);
  435.         }while(butt&3);
  436.  
  437.         do
  438.         {
  439.             read_joystick(1,x,y,&butt);
  440.         }while(!(butt&3));
  441.     }
  442. }
  443.  
  444. int sqrt_i(int a)
  445. {
  446.     int x,d,b;
  447.     int bt=0x80000000;
  448.     
  449.     if (a <= 0)    return (0);
  450.     
  451.     for (b=32; b>0; b--)
  452.     {
  453.         if (a&bt)
  454.             break;
  455.         else
  456.             bt>>=1;
  457.     }
  458.  
  459.     x=1<<(b>>1);
  460.  
  461.     while (d = ((((x * x - a) / x) + 1) >> 1)) 
  462.         x-=d;
  463.     return (x);
  464. }
  465.  
  466. void normalise_joy_i(volatile int *x,volatile int *y)
  467. {
  468.     int d;
  469.     d=(((*x)*(*x))+((*y)*(*y)));
  470.     d<<=12;
  471.     if (d>0)
  472.     {
  473.         d=sqrt_i(d);
  474.         *x<<=21;
  475.         *x/=d;
  476.         *y<<=21;
  477.         *y/=d;
  478.     }
  479.     else
  480.     {
  481.         *x=*y=0;
  482.     }
  483. }
  484.  
  485. int calc_dist_i(int x,int y)
  486. {
  487.     return (sqrt_i(x*x+y*y));
  488. }
  489.  
  490. void get_joy_dir1(volatile int *x,volatile int *y,volatile int *f)
  491. {
  492.     unsigned short rx,ry;
  493.     unsigned char sw;
  494.     int d;
  495.     *x=*y=0;
  496.     read_joy1(&rx,&ry,&sw);
  497.  
  498.     *x=rx-joy1_cnt_x;
  499.     *y=ry-joy1_cnt_y;
  500.  
  501.     ux1=*x;
  502.     ux2=*y;
  503.  
  504.  
  505.  
  506.     d=calc_dist_i((joy1_max_x-joy1_min_x),(joy1_max_y-joy1_min_y))*dead_zone/200;
  507.  
  508.     if (calc_dist_i(*x,*y)<d)
  509.     {
  510.         joy1_move=FALSE;
  511.         *x=*y=0;
  512.     }
  513.     else
  514.     {
  515.         joy1_move=TRUE;
  516.         normalise_joy_i(x,y);
  517.     }
  518.  
  519.     if (digital_joy1)
  520.     {
  521.         if (!joy1_move)
  522.         {
  523.             *x=*y=0;
  524.         }
  525.         else
  526.         {
  527.             int d=0;
  528.             if (*y>=0)
  529.             {
  530.                 if (*x>=0)
  531.                 {
  532.                     if (*x>*y)
  533.                     {
  534.                         if (*x>((*y)*2))
  535.                         {
  536.                             *x=TUNIT;
  537.                             *y=0;
  538.                         }
  539.                         else
  540.                         {
  541.                             *x=TDIAG;
  542.                             *y=TDIAG;
  543.                         }
  544.                     }
  545.                     else
  546.                     {
  547.                         if (*y>((*x)*2))
  548.                          {
  549.                             *x=0;
  550.                             *y=TUNIT;
  551.                         }
  552.                         else
  553.                         {
  554.                             *x=TDIAG;
  555.                             *y=TDIAG;
  556.                         }
  557.                     }
  558.                 }
  559.                 else
  560.                 {
  561.                     if (-*x>*y)
  562.                     {
  563.                         if (-*x>((*y)*2))
  564.                         {
  565.                             *x=-TUNIT;
  566.                             *y=0;
  567.                         }
  568.                         else
  569.                         {
  570.                             *x=-TDIAG;
  571.                             *y=TDIAG;
  572.                         }
  573.                     }
  574.                     else
  575.                     {
  576.                         if (*y>(-(*x)*2))
  577.                          {
  578.                             *x=0;
  579.                             *y=TUNIT;
  580.                         }
  581.                         else
  582.                         {
  583.                             *x=-TDIAG;
  584.                             *y=TDIAG;
  585.                         }
  586.                     }
  587.                 }
  588.             }
  589.             else
  590.             {
  591.                 if (*x>=0)
  592.                 {
  593.                     if (*x>-*y)
  594.                     {
  595.                         if (x>(-(*y)*2))
  596.                         {
  597.                             *x=TUNIT;
  598.                             *y=0;
  599.                         }
  600.                         else
  601.                         {
  602.                             *x=TDIAG;
  603.                             *y=-TDIAG;
  604.                         }
  605.                     }
  606.                     else
  607.                     {
  608.                         if (-*y>((*x)*2))
  609.                          {
  610.                             *x=0;
  611.                             *y=-TUNIT;
  612.                         }
  613.                         else
  614.                         {
  615.                             *x=TDIAG;
  616.                             *y=-TDIAG;
  617.                         }
  618.                     }
  619.                 }
  620.                 else
  621.                 {
  622.                     if (-*x>-*y)
  623.                     {
  624.                         if (-*x>(-*y*2))
  625.                         {
  626.                             *x=TUNIT;
  627.                             *y=0;
  628.                         }
  629.                         else
  630.                         {
  631.                             *x=-TDIAG;
  632.                             *y=-TDIAG;
  633.                         }
  634.                     }
  635.                     else
  636.                     {
  637.                         if (-*y>(-(*x)*2))
  638.                          {
  639.                             *x=0;
  640.                             *y=-TUNIT;
  641.                         }
  642.                         else
  643.                         {
  644.                             *x=-TDIAG;
  645.                             *y=-TDIAG;
  646.                         }
  647.                     }
  648.                 }
  649.             }
  650.         }
  651.     }
  652.     *f=sw;
  653. }
  654.  
  655.  
  656. void get_joy_dir2(volatile int *x,volatile int *y,volatile int *f)
  657. {
  658.     unsigned short rx,ry;
  659.     unsigned char sw;
  660.     int d;
  661.     *x=*y=0;
  662.     read_joy2(&rx,&ry,&sw);
  663.  
  664.     *x=rx-joy2_cnt_x;
  665.     *y=ry-joy2_cnt_y;
  666.     d=calc_dist_i((joy2_max_x-joy2_min_x),(joy2_max_y-joy2_min_y))*dead_zone/200;
  667.  
  668.     if (calc_dist_i(*x,*y)<d)
  669.     {
  670.         joy2_move=FALSE;
  671.         *x=*y=0;
  672.     }
  673.     else
  674.     {
  675.         joy2_move=TRUE;
  676.         normalise_joy_i(x,y);
  677.     }
  678.  
  679.     if (digital_joy2)
  680.     {
  681.         if (!joy2_move)
  682.         {
  683.             *x=*y=0;
  684.         }
  685.         else
  686.         {
  687.             int d=0;
  688.             if (*y>=0)
  689.             {
  690.                 if (*x>=0)
  691.                 {
  692.                     if (*x>*y)
  693.                     {
  694.                         if (*x>((*y)*2))
  695.                         {
  696.                             *x=TUNIT;
  697.                             *y=0;
  698.                         }
  699.                         else
  700.                         {
  701.                             *x=TDIAG;
  702.                             *y=TDIAG;
  703.                         }
  704.                     }
  705.                     else
  706.                     {
  707.                         if (*y>((*x)*2))
  708.                          {
  709.                             *x=0;
  710.                             *y=TUNIT;
  711.                         }
  712.                         else
  713.                         {
  714.                             *x=TDIAG;
  715.                             *y=TDIAG;
  716.                         }
  717.                     }
  718.                 }
  719.                 else
  720.                 {
  721.                     if (-*x>*y)
  722.                     {
  723.                         if (-*x>((*y)*2))
  724.                         {
  725.                             *x=-TUNIT;
  726.                             *y=0;
  727.                         }
  728.                         else
  729.                         {
  730.                             *x=-TDIAG;
  731.                             *y=TDIAG;
  732.                         }
  733.                     }
  734.                     else
  735.                     {
  736.                         if (*y>(-(*x)*2))
  737.                          {
  738.                             *x=0;
  739.                             *y=TUNIT;
  740.                         }
  741.                         else
  742.                         {
  743.                             *x=-TDIAG;
  744.                             *y=TDIAG;
  745.                         }
  746.                     }
  747.                 }
  748.             }
  749.             else
  750.             {
  751.                 if (*x>=0)
  752.                 {
  753.                     if (*x>-*y)
  754.                     {
  755.                         if (x>(-(*y)*2))
  756.                         {
  757.                             *x=TUNIT;
  758.                             *y=0;
  759.                         }
  760.                         else
  761.                         {
  762.                             *x=TDIAG;
  763.                             *y=-TDIAG;
  764.                         }
  765.                     }
  766.                     else
  767.                     {
  768.                         if (-*y>((*x)*2))
  769.                          {
  770.                             *x=0;
  771.                             *y=-TUNIT;
  772.                         }
  773.                         else
  774.                         {
  775.                             *x=TDIAG;
  776.                             *y=-TDIAG;
  777.                         }
  778.                     }
  779.                 }
  780.                 else
  781.                 {
  782.                     if (-*x>-*y)
  783.                     {
  784.                         if (-*x>(-*y*2))
  785.                         {
  786.                             *x=TUNIT;
  787.                             *y=0;
  788.                         }
  789.                         else
  790.                         {
  791.                             *x=-TDIAG;
  792.                             *y=-TDIAG;
  793.                         }
  794.                     }
  795.                     else
  796.                     {
  797.                         if (-*y>(-(*x)*2))
  798.                          {
  799.                             *x=0;
  800.                             *y=-TUNIT;
  801.                         }
  802.                         else
  803.                         {
  804.                             *x=-TDIAG;
  805.                             *y=-TDIAG;
  806.                         }
  807.                     }
  808.                 }
  809.             }
  810.         }
  811.     }
  812.     *f=sw;
  813. }
  814.  
  815.  
  816.  
  817. /////////////
  818. //  MOUSE  //
  819.  
  820. void get_mouse_dir(volatile struct user_config *user)
  821. {
  822.     int x,y;
  823.     ReportMouse();
  824.     x=Mouse.x-160;
  825.     y=Mouse.y-100;
  826.     x<<=15;
  827.     x/=160;
  828.     y<<=15;
  829.     y/=100;
  830.  
  831.     user->inp_fb=Mouse.b;
  832.     user->inp_x=x;
  833.     user->inp_y=y;
  834.  
  835.     MouseXYset(160,100);            // reset mouse origin.
  836. }
  837.  
  838.  
  839.  
  840. ////////////////
  841. //  KEYBOARD  //
  842.  
  843. short get_key_code(signed char *ks)
  844. {
  845.     int i;
  846.     short k=0;
  847.     signed short ki;
  848.     for (i=0; i<6; i++)
  849.     {
  850.         ki=*ks++;
  851.         if (ki<0)
  852.         {
  853.             ki=SPECIALK-ki;
  854.             if (keys[ki])
  855.                 k+=(1<<i);
  856.         }
  857.         else
  858.             if (keys[ki])
  859.                 k+=(1<<i);
  860.     }
  861.     return(k);
  862. }
  863.  
  864.  
  865.  
  866. void get_key_dir(volatile struct user_config *user,signed char *kb)
  867. {
  868.     short k;
  869.     k=get_key_code(kb);
  870.     user->inp_fb=FALSE;
  871.  
  872.     if (k>=32)            // Fire 2
  873.     {
  874.         user->inp_fb=2;
  875.         k-=32;
  876.     }
  877.  
  878.     if (k>=16)            // Fire 1
  879.     {
  880.         user->inp_fb+=1;
  881.         k-=16;
  882.     }
  883.  
  884.     switch(k)
  885.     {
  886.         case(0):
  887.             user->inp_x=0;
  888.             user->inp_y=0;
  889.             break;
  890.  
  891.         case(1):
  892.             user->inp_x=0;
  893.             user->inp_y=-32768;
  894.             break;
  895.  
  896.         case(2):
  897.             user->inp_x=0;
  898.             user->inp_y=32767;
  899.             break;
  900.             
  901.         case(4):
  902.             user->inp_x=-32768;
  903.             user->inp_y=0;
  904.             break;
  905.  
  906.         case(5):
  907.             user->inp_x=-TDIAG;
  908.             user->inp_y=-TDIAG;
  909.             break;
  910.  
  911.         case(6):
  912.             user->inp_x=-TDIAG;
  913.             user->inp_y=TDIAG;
  914.             break;
  915.  
  916.         case(7):
  917.             user->inp_x=-32768;
  918.             user->inp_y=0;
  919.             break;
  920.  
  921.         case(8):
  922.             user->inp_x=32767;
  923.             user->inp_y=0;
  924.             break;
  925.  
  926.         case(9):
  927.             user->inp_x=TDIAG;
  928.             user->inp_y=-TDIAG;
  929.             break;
  930.  
  931.         case(10):
  932.             user->inp_x=TDIAG;
  933.             user->inp_y=TDIAG;
  934.             break;
  935.  
  936.         case(11):
  937.             user->inp_x=32767;
  938.             user->inp_y=0;
  939.             break;
  940.  
  941.         case(13):
  942.             user->inp_x=0;
  943.             user->inp_y=-32768;
  944.             break;
  945.  
  946.         case(14):
  947.             user->inp_x=0;
  948.             user->inp_y=32767;
  949.             break;
  950.  
  951.         default:
  952.             user->inp_x=0;
  953.             user->inp_y=0;
  954.             break;
  955.     }
  956. }            
  957.  
  958.  
  959.  
  960. ///////////////
  961. //  GENERAL  //
  962.  
  963. void get_user_inputs()
  964. {
  965.     int i;
  966.  
  967.     ReadJoys(&joy_pos);
  968.  
  969.     for (i=0; i<num_of_users; i++)
  970.     {
  971.         switch(users[i].control)
  972.         {
  973.             case(JOY1_CTRL):
  974.                 get_joy_dir1(&joy1_x,&joy1_y,&joy1_fire);
  975.                 users[i].inp_x=joy1_x;
  976.                 users[i].inp_y=joy1_y;
  977.                 users[i].inp_fb=joy1_fire;
  978.                 break;
  979.             
  980.             case(JOY2_CTRL):
  981.                 get_joy_dir2(&joy2_x,&joy2_y,&joy2_fire);
  982.                 users[i].inp_x=joy2_x;
  983.                 users[i].inp_y=joy2_y;
  984.                 users[i].inp_fb=joy2_fire;
  985.                 break;
  986.             
  987.             case(KEY1_CTRL):
  988.                 get_key_dir(&users[i],key1);
  989.                 break;
  990.  
  991.             case(KEY2_CTRL):
  992.                 get_key_dir(&users[i],key2);
  993.                 break;
  994.  
  995.             case(MOUSE_CTRL):
  996.                 get_mouse_dir(&users[i]);
  997.                 break;
  998.         }
  999.     }
  1000. }
  1001.  
  1002. void process_user_inputs()
  1003. {
  1004.     int x,y,i,a,b;
  1005.  
  1006.     for (i=0; i<num_of_users; i++)
  1007.     {
  1008.         if (users[i].type && users[i].control!=NET_CTRL)        // Not computer or net guy
  1009.         {
  1010.             x=users[i].inp_x;
  1011.             y=users[i].inp_y;
  1012.             a=x*icth;
  1013.             b=y*isth;
  1014.             a=(a-b)>>15;
  1015.  
  1016.             if (a<-32767)
  1017.                 a=-32767;
  1018.             if (a>32767)
  1019.                 a=32767;
  1020.  
  1021.             users_dir_i[writeptr][i].x_f1=a;
  1022.  
  1023.             a=y*icth;
  1024.             b=x*isth;
  1025.             a=(a+b)>>15;
  1026.  
  1027.             if (a<-32767)
  1028.                 a=-32767;
  1029.             if (a>32767)
  1030.                 a=32767;
  1031.  
  1032.             users_dir_i[writeptr][i].y_f2=a;
  1033.  
  1034.             users_dir_i[writeptr][i].x_f1&=0xfffe;
  1035.             users_dir_i[writeptr][i].x_f1|=(users[i].inp_fb&1);
  1036.             users_dir_i[writeptr][i].y_f2&=0xfffe;
  1037.             users_dir_i[writeptr][i].y_f2|=((users[i].inp_fb&2)>>1);
  1038.             users[i].inp_ox=x;
  1039.             users[i].inp_oy=y;
  1040.         }
  1041.     }
  1042. }
  1043.  
  1044.  
  1045.  
  1046. /**************************/
  1047. /*  INTERRUPT TIMER CODE  */
  1048. /**************************/
  1049.  
  1050.  
  1051. unsigned int NetworkHandle; // Handle for this timer routine
  1052.  
  1053. void __far nethandler(void)
  1054.     {
  1055.     int i;
  1056.     count++;
  1057.     ftick+=game_speed;
  1058.     if (ftick>=TIMER_SPEED)
  1059.         {
  1060.         do    
  1061.             ftick-=TIMER_SPEED;
  1062.         while (ftick>TIMER_SPEED);
  1063.         tick++;
  1064.         hold_loop=1; //ACTIVE
  1065.  
  1066.         if (!old_mf)
  1067.         {
  1068.             if (netsetup_on)                      // If in network setup...
  1069.                 {
  1070.                 if (network_on)
  1071.                     NetInitialisation();            // Scan for new nodes and player data
  1072.                 }
  1073.             else
  1074.                 {
  1075.                 if (network_on)                    // If a network game...
  1076.                     {
  1077.                     if (wConsoleNode==master)                                        // If master...
  1078.                         {
  1079.                         if ( start_multiple==network_on-1 )                      // If all data sent last frame
  1080.                             {
  1081.                             for (i=0;i<MAX_NET_USERS;i++)
  1082.                                 {
  1083.                                 users_dir_i[writeptr][i].x_f1=users_dir_i[(writeptr-1)&511][i].x_f1; // Copy all last input data for defaults
  1084.                                 users_dir_i[writeptr][i].y_f2=users_dir_i[(writeptr-1)&511][i].y_f2; // ...
  1085.                                 }
  1086.                             get_user_inputs();                                          // Read own input data..
  1087.                             process_user_inputs();
  1088.                             if (!(tick&7)) putch('.');
  1089.                             receive_all_singles();                                    // Receive input data from all other machines
  1090.                             }
  1091.                         if (active_nodes==network_on)                                // Only start transmitting when ready
  1092.                             {
  1093.                             if (start_multiple!=network_on-1 || !paused)        // Stop sending if paused, and block fully transmitted
  1094.                                 {
  1095.                                 send_multiple();
  1096.                                 if ( start_multiple==network_on-1 )             // If block fully transmitted, move to next
  1097.                                     {
  1098.                                     writeptr++;
  1099.                                     writeptr&=511;
  1100.                                     }
  1101.                                 }
  1102.                             }
  1103.                         }
  1104.                     else                                // If slave...
  1105.                         {
  1106.                         get_user_inputs();        // Read own input data
  1107.                         process_user_inputs();
  1108.  
  1109.                         for (i=0; i<network_on; i++)
  1110.                             if (users[i].type && users[i].control!=NET_CTRL &&                                        // If local human user,... 
  1111.                               (users_dir_i[writeptr][i].x_f1!=users_dir_i[(writeptr-1)&511][i].x_f1 ||    // and input has changed... 
  1112.                                 users_dir_i[writeptr][i].y_f2!=users_dir_i[(writeptr-1)&511][i].y_f2) )
  1113.                                 send_single(i);                                                                                // then send to master
  1114.  
  1115.                         receive_multiple();      // Receive all input data from master
  1116.                         }
  1117.                     }
  1118.                 else                  // If not a network game...
  1119.                     {
  1120.                     if (!paused)    // and not paused...
  1121.                         {
  1122.                         get_user_inputs();
  1123.                         process_user_inputs();
  1124.                         writeptr++;
  1125.                         writeptr&=511;                // Move to next block
  1126.                         }
  1127.                     }
  1128.                 }
  1129.             }
  1130.         }
  1131.     }
  1132.  
  1133. // Wait for next interrupt
  1134. void TickPause()
  1135. {
  1136.     int tcount;
  1137.     tcount=count;
  1138.     while (count<=tcount+TIMER_FRAC);
  1139. }
  1140.  
  1141.  
  1142.  
  1143. /********************/
  1144. /*  RECEIVING DATA  */
  1145. /********************/
  1146.  
  1147. // Routine for master to receive all input data types.
  1148. void    receive_all_singles()
  1149. {
  1150.     packet_header    *header;
  1151.     packet_single    *data;
  1152.     packet_info        info;
  1153.     PSTR    pPacket;
  1154.  
  1155.     if (network_on)
  1156.     {
  1157.         header=&in_header;
  1158.         while (hmiNETNOWGetHeader((PSTR)header,sizeof(packet_header),&pPacket))
  1159.         {
  1160.             switch(header->type)
  1161.             {
  1162.                 case NET_ONLINE:
  1163.                     hmiNETNOWGetBlock(pPacket,(PSTR) &info,sizeof(packet_info));
  1164.  
  1165.                     // Master receiving data
  1166.  
  1167.                     break;
  1168.  
  1169.                 case NET_SINGLE:
  1170.                     data=&users_dir_i[writeptr][header->player];
  1171.                     hmiNETNOWGetBlock(pPacket,(PSTR)data,sizeof(packet_single));
  1172.                     break;
  1173.  
  1174.                 case NET_READY:
  1175.         puts("NET_READY received.");
  1176.                     active_nodes++;
  1177.                     break;
  1178.  
  1179.                 case NET_QUIT:
  1180.                      hmiNETNOWPostListen();
  1181.                     send_quit();    // All quit if anyone quits!
  1182.                     break;
  1183.  
  1184.                 case NET_PAUSE:
  1185.                     slave_pause=TRUE;
  1186.                     break;
  1187.             }
  1188.              hmiNETNOWPostListen();
  1189.         }
  1190.     }
  1191. }
  1192.  
  1193. // Routine for slaves to receive all input data types.
  1194. void    receive_multiple()
  1195. {
  1196.     packet_header    *header;
  1197.     packet_multiple *data;
  1198.     packet_single    *sing;
  1199.     packet_seed        *seed;
  1200.     packet_info        info;
  1201.     packet_pause    pausep;
  1202.     PSTR    pPacket;
  1203.     if (network_on)
  1204.     {
  1205.         header=&in_header;
  1206.         sing=&test_single;
  1207.         seed=&test_seed;
  1208.         while (hmiNETNOWGetHeader((PSTR)header,sizeof(packet_header),&pPacket))
  1209.         {
  1210.             switch(header->type)
  1211.             {
  1212.                 case NET_ONLINE:
  1213.                     hmiNETNOWGetBlock(pPacket,(PSTR) &info,sizeof(packet_info));
  1214.  
  1215.                     // Slave receiving data
  1216.  
  1217.                     break;
  1218.  
  1219.                 case NET_MULTIPLE:
  1220.                     data=(packet_multiple *)users_dir_i[writeptr];
  1221.                     hmiNETNOWGetBlock(pPacket,(PSTR)data,sizeof(packet_multiple));
  1222.                     writeptr++;
  1223.                     writeptr&=511;
  1224.                     if (!net_quit) active_nodes=network_on;
  1225.                     break;
  1226.  
  1227.                 case NET_SEED:
  1228.                     // Slave receiving seed
  1229.                     hmiNETNOWGetBlock(pPacket,(PSTR)seed,sizeof(packet_seed));
  1230.                     received_seed=seed->num?seed->num:1;
  1231.                     break;
  1232.  
  1233.                 case NET_QUIT:
  1234.                     net_quit=TRUE;
  1235.                     break;
  1236.  
  1237.                 case NET_PAUSE:
  1238.                     hmiNETNOWGetBlock(pPacket,(PSTR) &pausep,sizeof(packet_pause));
  1239.                     paused=pausep.paused;
  1240.                     break;
  1241.             }
  1242.              hmiNETNOWPostListen();
  1243.         }
  1244.     }
  1245. }
  1246.  
  1247.  
  1248.  
  1249. /******************/
  1250. /*  SENDING DATA  */
  1251. /******************/
  1252.  
  1253. //Master transmits all input data, sends NET_MULTIPLE header and multiple packet
  1254. void    send_multiple()
  1255. {
  1256.     packet_header        *header;
  1257.     packet_multiple    *data;
  1258.     int    i,sent;
  1259.  
  1260.     if (network_on)
  1261.     {
  1262.         header=&p_header;
  1263.         data=&test_multiple;
  1264.  
  1265.         header->player=wConsoleNode;    
  1266.         header->type=NET_MULTIPLE;
  1267.         header->frame=frame_number;
  1268.         frame_number++;
  1269.  
  1270. //        data=(packet_single *)users_dir_i[writeptr];
  1271.         for (i=0;i<network_on;i++)
  1272.         {
  1273.             data->inp[i].x=users_dir_i[writeptr][i].x_f1;
  1274.             data->inp[i].y=users_dir_i[writeptr][i].y_f2;
  1275.         }
  1276.  
  1277.         i=abs(start_multiple);
  1278.         sent=TRUE;
  1279.         while (i>=0 && sent)
  1280.         {
  1281.             if (i!=master)
  1282.                 sent=hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,sizeof(packet_multiple),i);
  1283.             else
  1284.                 sent=TRUE;
  1285.             if (sent) i--;
  1286.         }
  1287.  
  1288.         if (sent) start_multiple=network_on-1;
  1289.         else start_multiple=-i;
  1290.     }
  1291. }
  1292.  
  1293.  
  1294. // Slave sends own input data, send NET_SINGLE header and input packet to master
  1295. void    send_single(int plyr)
  1296. {
  1297.     packet_header    *header;
  1298.     packet_single    *data;
  1299.     int    wait;
  1300.  
  1301.     if (network_on)
  1302.     {
  1303.         header=&p_header;
  1304.         data=&test_single;
  1305.  
  1306.         header->player=wConsoleNode;
  1307.         header->type=NET_SINGLE;
  1308.         data=(packet_single *)&users_dir_i[writeptr][plyr];
  1309.  
  1310. //        do
  1311.             wait=hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,sizeof(packet_single),master);
  1312. //        while( !wait );
  1313.     }
  1314. }
  1315.  
  1316.  
  1317. // Slave is ready to play, send NET_READY header and null data packet to master
  1318. void    send_ready()
  1319. {
  1320.     packet_header    *header;
  1321.     packet_data        *data;
  1322.  
  1323.     if (network_on)
  1324.     {
  1325.         header=&p_header;
  1326.         data=&p_data;
  1327.  
  1328.         header->player=wConsoleNode;    
  1329.         header->type=NET_READY;
  1330.  
  1331.         if (wConsoleNode==master)
  1332.             active_nodes++;            // If master just increase active nodes
  1333.         else
  1334.         {puts("NET_READY sent.");
  1335.         while( !hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,0,master) );
  1336.         }
  1337.     }
  1338. }
  1339.  
  1340.  
  1341. // Master sends a random seed, send NET_SEED header and seed packet to slaves
  1342. void    send_seed(int num)
  1343. {
  1344.     packet_header    *header;
  1345.     packet_seed        *data;
  1346.     int    i;
  1347.  
  1348.     if (network_on)
  1349.     {
  1350.         header=&p_header;
  1351.         data=&test_seed;
  1352.  
  1353.         header->player=wConsoleNode;    
  1354.         header->type=NET_SEED;
  1355.         data->num=num;
  1356.  
  1357.         for (i=0;i<network_on;i++)
  1358.             if (i!=master)
  1359.                 while( !hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,sizeof(packet_seed),i) );
  1360.  
  1361. //        puts("Net_seed sent");
  1362.     }
  1363. }
  1364.  
  1365.  
  1366. // Send a message, send NET_MESSAGE header and message packet containing string (watch maximum length) to everyone
  1367. void    send_mes(char *m)
  1368. {
  1369.     packet_header    *header;
  1370.     packet_data        *data;
  1371.     WORD    head_size,data_size;
  1372.     int    i;
  1373.  
  1374.     if (network_on)
  1375.     {
  1376.         header=&p_header;
  1377.         data=&p_data;
  1378.  
  1379.         strcpy(data->mes,m);
  1380.         header->player=wConsoleNode;    
  1381.         header->type=NET_MESSAGE;
  1382.  
  1383.         for (i=0;i<network_on;i++)
  1384.         {
  1385.             if (i!=wConsoleNode)
  1386.                 while( !hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,sizeof(packet_data),i) );
  1387.         }
  1388.     }
  1389. }
  1390.  
  1391.  
  1392. // Player is to quit, send NET_QUIT header and null data packet, if master quits, all nodes quit
  1393. void    send_quit()
  1394. {
  1395.     packet_header    *header;
  1396.     packet_data        *data;
  1397.     WORD                head_size,data_size;
  1398.     int                i;
  1399.  
  1400.     if (network_on)
  1401.     {
  1402.         header=&p_header;
  1403.         data=&p_data;
  1404.  
  1405.         header->player=wConsoleNode;    
  1406.         header->type=NET_QUIT;
  1407.  
  1408.         if (wConsoleNode==master)
  1409.         {
  1410.             for (i=0;i<network_on;i++)
  1411.                 if (i!=wConsoleNode)
  1412.                     while( !hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,0,i) );
  1413.  
  1414.             net_quit=TRUE;
  1415.         }
  1416.         else    while( !hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) data,0,master) );
  1417.     }
  1418. }
  1419.  
  1420.  
  1421. // Send pause request, send NET_PAUSE header and pause packet to master
  1422. void    send_pause()
  1423.     {
  1424.     packet_header header;
  1425.     packet_pause  data;
  1426.  
  1427.     if (network_on)
  1428.         {
  1429.         header.type=NET_PAUSE;
  1430.         data.paused=!paused;                //request to invert! (not used by master - simply inverts its copy!)
  1431.         while (!hmiNETNOWSendData((PSTR) &header,sizeof(packet_header),(PSTR) &data,sizeof(packet_pause),master));
  1432.         }
  1433.     }
  1434.  
  1435.  
  1436. // Transmit pause to slaves, send NET_PAUSE header and pause packet to all slaves
  1437. void    transmitpausetoslaves(void)
  1438.     {
  1439.     //transmit new pause status to slaves
  1440.     packet_header header;
  1441.     packet_pause  data;
  1442.     int    i;
  1443.  
  1444.     if (network_on)
  1445.         {
  1446.         header.type=NET_PAUSE;
  1447.         data.paused=paused;                //request to invert!
  1448.         for (i=0;i<network_on;i++)
  1449.             if (i!=master)
  1450.                 while (!hmiNETNOWSendData((PSTR) &header,sizeof(packet_header),(PSTR) &data,sizeof(packet_pause),i));
  1451.         }
  1452.     }
  1453.  
  1454.  
  1455.  
  1456. /****************************/
  1457. /*  INITIALISE/SYNCHRONISE  */
  1458. /****************************/
  1459.  
  1460.  
  1461. // Send initialisation data to or from newly logged on node (broadcast message necessary, others must discard)
  1462. void    TransmitInit(void)
  1463.     {
  1464.     packet_header header;
  1465.     packet_info      info;
  1466.     if (network_on)
  1467.         {
  1468.         // Send address & data
  1469.         info.address=laddress;
  1470.         info.Team_A=Team_A;
  1471.         info.Team_B=Team_B;
  1472.         info.Team=TeamChoice;
  1473.         info.Player=PlayerChoice;
  1474.  
  1475.         header.type=NET_ONLINE;
  1476.         while (!hmiNETNOWSendData((PSTR) &header,sizeof(packet_header),(PSTR) &info,sizeof(packet_info),_NETNOW_BROADCAST));
  1477.         }
  1478.     }
  1479.  
  1480.  
  1481. // Finds if supplied address is in address list
  1482. int FindAddress(_NETNOW_NODE_ADDR daddress)
  1483. {
  1484.     int    duplic=-1;
  1485.     int    i,j;
  1486.     char    diff;
  1487.     char    *a1,*a2;
  1488.     int    sizeaddress;
  1489.  
  1490.     sizeaddress=sizeof(_NETNOW_NODE_ADDR);
  1491.     for (i=0;i<network_on;i++)
  1492.         {
  1493.         diff=FALSE;
  1494.         for (j=0;j<sizeaddress;j++)
  1495.             {
  1496.             a1=(char *) &address[i];
  1497.             a2=(char *) &daddress;
  1498.             if (*(a1+j)!=*(a2+j)) diff=TRUE;
  1499.             }
  1500.         if (!diff) { duplic=i; break; }
  1501.         }
  1502.     return (duplic);
  1503. }
  1504.  
  1505.  
  1506. void    NetInitialisation()
  1507. {
  1508.     packet_header    header;
  1509.     packet_info        info;
  1510.     packet_seed        *seed;
  1511.     PSTR    pPacket;
  1512.     _NETNOW_NODE_ADDR taddress;
  1513.     int    error,Node;
  1514. int i;
  1515.     seed=&test_seed;
  1516. //    wNETNodes=network_on;
  1517.     while (hmiNETNOWGetHeader((PSTR) &header,sizeof(packet_header),&pPacket))
  1518.         {
  1519.         switch(header.type)
  1520.             {
  1521.  
  1522.             // Received online broadcast...
  1523.             case NET_ONLINE:
  1524.                 hmiNETNOWGetBlock(pPacket,(PSTR) &info,sizeof(packet_info));
  1525.  
  1526.                 // Have we already added this node (will happen a lot because this is a broadcast message)
  1527.                 if (FindAddress(info.address)<0 && !NetDone)
  1528.                 {    
  1529.                     // This is a new node - add it in.
  1530.                     error=hmiNETNOWAddNode(&info.address);
  1531.                     switch(error)
  1532.                     {
  1533.                         case _NETNOW_ADD_COMPLETE:
  1534.                             hmiNETNOWSortNodes();
  1535.                             address[network_on]=info.address;
  1536.                             if (info.Team_A>=0) Team_A=info.Team_A,Team_B=info.Team_B;
  1537.                             Teams[network_on]=info.Team;
  1538.                             Players[network_on]=info.Player;
  1539.                             network_on++;
  1540.  
  1541.                             // Send own data back through a NET_ONLINE message, those already on will ignore!!!
  1542.                             TransmitInit();
  1543.                             break;
  1544.  
  1545.                         case _NETNOW_ADD_DUPLICATE:
  1546.                             exit(1);
  1547.                             break;
  1548.                         case _NETNOW_ADD_LIST_FULL:
  1549.                             exit(1);
  1550.                             break;
  1551.                         default:
  1552.                             break;
  1553.                     }
  1554.                 }
  1555.                 break;
  1556.  
  1557.             // Received go message, find node number; no more people can log on now.
  1558.             case    NET_GO:
  1559.                 if (!net_players[header.player])
  1560.                 {
  1561.                     NetDone++;
  1562.                     net_players[header.player]=TRUE;
  1563. //                    if (NetDone<=1)
  1564. //                    {
  1565. //                        SendNetDone();
  1566. //                        FoundNodes();
  1567. //                        SendPlayerInfo();
  1568. //                    }
  1569.                 }
  1570.                 break;
  1571.  
  1572.             // Received initialisation info (team or player choices)
  1573.             case NET_INFO:
  1574.                 hmiNETNOWGetBlock(pPacket,(PSTR) &info,sizeof(packet_info));
  1575.  
  1576.                 // Set up player data
  1577.                 if (info.Team_A>=0)
  1578.                     {
  1579.                     Team_A=info.Team_A;
  1580.                    Team_B=info.Team_B;
  1581.                     }
  1582.                 else
  1583.                     {
  1584.                     Node=FindAddress(info.address);
  1585.                     if (header.player>=0)
  1586.                         {
  1587.                         // Informant has sent his node value, swap own data structures to match...
  1588.                         taddress=address[Node];
  1589.                         address[Node]=address[header.player];
  1590.                         address[header.player]=taddress;
  1591.                         Teams[Node]=Teams[header.player];
  1592.                         Players[Node]=Players[header.player];
  1593.                         Node=header.player;
  1594.                         }
  1595.                     Teams[Node]=info.Team;
  1596.                     Players[Node]=info.Player;
  1597.                     }
  1598.                 break;
  1599.  
  1600.             // Received seed from master
  1601.              case NET_SEED:
  1602. //                puts("Net_seed found");
  1603.                 hmiNETNOWGetBlock(pPacket,(PSTR)seed,sizeof(packet_seed));
  1604.                 received_seed=seed->num?seed->num:1;
  1605.                 break;
  1606.  
  1607.             // Received quit command from master
  1608.             case NET_QUIT:
  1609.                 puts("Net_quit found");
  1610.     
  1611.                 net_quit=TRUE;
  1612.                 break;
  1613.             }
  1614.          hmiNETNOWPostListen();
  1615.         }
  1616. }
  1617.  
  1618.  
  1619. // Finished waiting for new nodes, find no of nodes and own node number
  1620. void    FoundNodes()
  1621. {
  1622.     if (master!=0)
  1623.     {
  1624.         network_on=hmiNETNOWGetActiveNodes();        // Get active nodes
  1625.         wConsoleNode=hmiNETNOWGetConsoleNode();    // Get console node
  1626.         master=0;
  1627. //        num_of_users=network_on;
  1628.         start_multiple=network_on-1;
  1629.     }
  1630. }
  1631.  
  1632.  
  1633. // Player presses start
  1634. void    SendNetDone()
  1635. {
  1636.     packet_header header;
  1637.     packet_data      data;
  1638.     int    i,node,tval;
  1639.  
  1640.     NetDone++;
  1641.     FoundNodes();
  1642.  
  1643.     node=FindAddress(laddress);
  1644.     address[node]=address[wConsoleNode];
  1645.     address[wConsoleNode]=laddress;
  1646.     tval=Teams[node];
  1647.     Teams[node]=Teams[wConsoleNode];
  1648.     Teams[wConsoleNode]=tval;
  1649.     tval=Players[node];
  1650.     Players[node]=Players[wConsoleNode];
  1651.     Players[wConsoleNode]=tval;
  1652.     net_players[wConsoleNode]=TRUE;
  1653.  
  1654.     header.player=wConsoleNode;
  1655.      header.type=NET_GO;
  1656.  
  1657.     for (i=0;i<network_on;i++)
  1658.         if (i!=wConsoleNode)
  1659.              while (!hmiNETNOWSendData((PSTR) &header,sizeof(packet_header),(PSTR) &data,0,i));
  1660.  
  1661.     SendPlayerInfo();
  1662. }
  1663.  
  1664.  
  1665. void    SendTeamInfo()
  1666. {
  1667.     packet_header    *header;
  1668.     packet_info        info;
  1669.     int    i;
  1670.  
  1671.     if (network_on)
  1672.     {
  1673.         header=&p_header;
  1674.  
  1675.         // Set up team data
  1676.         info.Team_A=Team_A;
  1677.         info.Team_B=Team_B;
  1678.  
  1679.         header->type=NET_INFO;
  1680.         for (i=0;i<network_on;i++)
  1681.             if (i!=wConsoleNode)
  1682.                 while (!hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) &info,sizeof(packet_info),i));
  1683.     }
  1684. }
  1685.  
  1686. void    SendPlayerInfo()
  1687. {
  1688.     packet_header    *header;
  1689.     packet_info        info;
  1690.     int    i;
  1691.  
  1692.     if (network_on)
  1693.     {
  1694.         header=&p_header;
  1695.  
  1696.         // Set up player data
  1697.         info.Team_A=info.Team_B=-1;
  1698.         info.Team=TeamChoice;
  1699.         info.Player=PlayerChoice;
  1700.         info.address=address[(wConsoleNode<0) ? 0 : wConsoleNode];
  1701.  
  1702.         header->player=wConsoleNode;    
  1703.         header->type=NET_INFO;
  1704.  
  1705.         for (i=0;i<network_on;i++)
  1706.             if (i!=wConsoleNode)
  1707.                 while( !hmiNETNOWSendData((PSTR) header,sizeof(packet_header),(PSTR) &info,sizeof(packet_info),i) );
  1708.     }
  1709. }
  1710.  
  1711.  
  1712. void pausehandler()
  1713.     {
  1714.     if (pause_request)
  1715.         {
  1716.         if (!network_on)
  1717.             {
  1718.             paused=!paused;
  1719.             }
  1720.         else
  1721.             {
  1722.             if (wConsoleNode==master)
  1723.                 {
  1724.                 //master initiated pause.
  1725.                 paused=!paused;
  1726.                 transmitpausetoslaves();            //all machines will pause
  1727.                 }
  1728.             else
  1729.                 {
  1730.                 send_pause();                    //send pause to master
  1731.                 }
  1732.             }
  1733.         pause_request=FALSE;
  1734.         }
  1735.  
  1736.     if (network_on && slave_pause && wConsoleNode==master)
  1737.         {
  1738.         //master received a request to pause from slave
  1739.         paused=!paused;
  1740.         transmitpausetoslaves();
  1741.         slave_pause=FALSE;
  1742.         }
  1743.     }
  1744.  
  1745.  
  1746.  
  1747. /*****************/
  1748. /* NETWORK SETUP */
  1749. /*****************/
  1750.  
  1751. int Initialise_Network()
  1752. {
  1753.     int i;
  1754. //    active_nodes=1;        // if no network 1 player.
  1755.     net_quit=FALSE;
  1756.     master=-1;
  1757.     wConsoleNode=-1;
  1758.     if (network_on)
  1759.     {
  1760.         received_seed=FALSE;
  1761.         frame_number=0;
  1762.         active_nodes=0;        //reset if network on.
  1763.  
  1764. //        puts ("INTIALIZING NETWORK.");
  1765.  
  1766.         if ( hmiNETNOWInitSystem( 16 ) != _NETNOW_NO_ERROR )
  1767.         {
  1768. //            puts( "ERROR: NetNOW! could not locate IPX or NetBIOS!" );
  1769.             network_on=FALSE;
  1770.             netsetup_on=FALSE;
  1771.             old_mf=TRUE;
  1772.             return(-1);                //...
  1773.         }
  1774.         else
  1775.         {
  1776. //            puts( "NetNOW! system initialized!" );
  1777.             // Check for information display
  1778.             if ( wNETInfoFlag )
  1779.                 switch( hmiNETNOWGetNetworkType() )
  1780.                 {
  1781.                     case  _NETNOW_IPX    :
  1782.                         // display type
  1783. //                        puts( "Network is using a IPX based protocol." );
  1784.                         break;
  1785.                     case  _NETNOW_NETBIOS:
  1786.                         // display type
  1787. //                        puts( "Network is using a NetBIOS based protocol." );
  1788.                         break;
  1789.                 }
  1790.  
  1791.             while (hmiNETNOWPostListen());
  1792.  
  1793.             for (i=0;i<MAX_NET_USERS;i++)    net_players[i]=FALSE;
  1794.  
  1795.             hmiNETNOWGetNetworkAddr(&laddress);        //read this nodes address.
  1796.             address[0]=laddress;
  1797.             TransmitInit();                                //send NET_ONLINE (with address) as a broadcast to other machines
  1798.  
  1799.             NetDone=0;
  1800.             network_on=onetwork_on=1;
  1801.         }    
  1802.     }
  1803.     return (0);
  1804. }
  1805.  
  1806.  
  1807. void    close_network()
  1808. {
  1809.     packet_header    *header;
  1810.     PSTR    pPacket;
  1811.     short    head_size;
  1812.     if (network_on)
  1813.     {
  1814. //        puts("Resetting network.");
  1815.         header=&in_header;
  1816.         hmiNETNOWPostListen();
  1817.         while (hmiNETNOWGetHeader((PSTR)header,sizeof(packet_header),&pPacket))    hmiNETNOWPostListen();
  1818.         hmiNETNOWUnInitSystem();
  1819. //        puts("Network removed.");
  1820.     }
  1821.     netsetup_on=FALSE;
  1822.     network_on=FALSE;
  1823.     old_mf=TRUE;
  1824.     master=-1;
  1825. }
  1826.  
  1827.  
  1828.  
  1829. int Poll_Network()
  1830. {
  1831.     static scount=0;
  1832.     int i,s;
  1833. //    if (!(count&127)) putch('.');
  1834. //    if (keys[0x13]) {close_network();exit(1);}
  1835.     if (NetDone<network_on)
  1836.     {
  1837.         return (-1);
  1838.         if (onetwork_on!=network_on)
  1839.         {
  1840.             for (i=onetwork_on;i<network_on;i++)
  1841.                 printf("\nFound node %d\n",i);
  1842.             onetwork_on=network_on;
  1843.         }
  1844.         return (-1);
  1845.     }
  1846.     else
  1847.     {
  1848.         if (wConsoleNode==master)
  1849.             {
  1850.             if (!(s=clock()&0xffff)) s=1;
  1851.             send_seed(s);
  1852.             }
  1853.         else
  1854.             while(!(s=received_seed));
  1855.         return (s);
  1856.     }
  1857. }
  1858.  
  1859.  
  1860. int Start_Network_Game()
  1861. {
  1862.     int i;
  1863.     Team_A=-1;
  1864.     Team_B=-1;
  1865.     for (i=0; i<MAX_NET_USERS; i++)
  1866.     {
  1867.         Teams[i]=-1;
  1868.         Players[i]=-1;
  1869.     }
  1870.     TeamChoice=-1;
  1871.     PlayerChoice=-1;
  1872.     network_on=netsetup_on=TRUE;
  1873.     old_mf=FALSE;
  1874.     return (Initialise_Network());
  1875. }
  1876.  
  1877.  
  1878. void Network_Play_Ready()
  1879. {
  1880.     if (network_on) 
  1881.     {
  1882.         send_ready();
  1883.         while (active_nodes<network_on);    // escape key?
  1884.     }
  1885. }
  1886.  
  1887.  
  1888. void Quit_Network_Play()
  1889. {
  1890.     if (network_on)
  1891.     {
  1892.         send_quit();
  1893.         while (!net_quit); // Timeout??
  1894.         active_nodes=0;
  1895.     }
  1896. }
  1897.  
  1898.  
  1899. void End_Network_Game()
  1900. {
  1901.     if (network_on)
  1902.         close_network();
  1903. }
  1904.  
  1905. int NetTest()
  1906. {
  1907.     int i,Starts,Seed,stick;
  1908.     char TeamsSelected,ChoiceAltered,StartPressed;
  1909.  
  1910.  
  1911.     //...whatever front end stuff comes first...
  1912.  
  1913.  
  1914.     // There are variables Team_A & Team_B for teams playing, TeamChoice for this players choice from these
  1915.     // two, (value 0 or 1), PlayerChoice is the player in the team chosen, 1 to 11 (1 indicates auto-player).
  1916.     // The variable network_on is the number of players currently logged on to the game, and the arrays
  1917.     // Teams[] and Players[] give the current selections of all the players from 0 to network_on-1, (Note, which is
  1918.     // your entry in this array is NOT stored!), you may also want to use the local variable Starts (see below)
  1919.  
  1920.  
  1921.     if (Start_Network_Game()<0)    // Initialises Team_A, Team_B, TeamChoice & PlayerChoice and starts network
  1922.         {
  1923.         old_mf=1;
  1924.         return(-1);
  1925.         }
  1926.     TickPause();
  1927.  
  1928.     stick=tick;
  1929.  
  1930.     // Choose teams to play
  1931.     while (Team_A<0)  // Wait until they are chosen  (add escape key?)
  1932.     {
  1933.         TeamsSelected=1;    // Your condition
  1934.  
  1935.         // If local user sets Team_A & Team_B first send them using SendTeamInfo()
  1936.          if (TeamsSelected)
  1937.         {
  1938.             Team_A=14;Team_B=0;
  1939.             SendTeamInfo();
  1940.         }
  1941.         TickPause();
  1942. Poll_Network();
  1943.  
  1944.     }
  1945.  
  1946. //printf("\nTeam %d plays team %d\n",Team_A,Team_B);
  1947.  
  1948.  
  1949.     // Teams are chosen, allow player to choose team to play for and player to control...
  1950.     // 2 is added to TeamChoice when player presses start 
  1951. //    puts("Choose team, 'A' or 'B', then press return");
  1952.     do 
  1953.     {
  1954.         // If start has been pressed, no further selection allowed
  1955.         if (TeamChoice<2)
  1956.         {
  1957.  
  1958.             // Your condition
  1959.             ChoiceAltered=machine_no;
  1960. //            if    (keys[0x1e]) ChoiceAltered=1;
  1961. //            if    (keys[0x30]) ChoiceAltered=2;
  1962.  
  1963.             // If local user alters TeamChoice or PlayerChoice then call SendPlayerInfo();
  1964.             // Must check Players and Teams arrays to make sure no-one else has chosen the same
  1965.             if (ChoiceAltered)
  1966.             {
  1967.                 TeamChoice=ChoiceAltered-1;
  1968. //                if (TeamChoice==0) puts("Team A chosen");
  1969. //                else puts("Team B chosen");
  1970.                 PlayerChoice=1;
  1971.                 SendPlayerInfo();
  1972.             }
  1973.  
  1974.             // Your condition
  1975.             StartPressed=1;//(keys[0x1c]);
  1976.             
  1977.             // If the start button is pressed and team is chosen add 2 to TeamChoice...
  1978.             if (TeamChoice>=0 && PlayerChoice>=0 && StartPressed)
  1979.             {
  1980. //                puts("OK, now waiting for others to start");
  1981.                 TeamChoice+=2;
  1982.                 SendPlayerInfo();
  1983.             }
  1984.         }
  1985.         TickPause();
  1986. Poll_Network();
  1987.  
  1988.         // Condition indicating selection complete (player chosen + start button), perhaps Starts should be displayed
  1989.         Starts=0;
  1990.         for (i=0;i<network_on;i++)
  1991.             if (Teams[i]>=2) Starts++;
  1992.     } while ((Starts<network_on || Starts<=1) && tick<stick+10*20); // Must be more than one player!
  1993.  
  1994.     if (tick<stick+10*20)
  1995.         {
  1996.         // Final syncronisation (sorts nodes and sets random seed)
  1997.         SendNetDone();
  1998.         while ((Seed=Poll_Network())<0);  // (Add escape key?)
  1999.         netsetup_on=FALSE;
  2000.  
  2001.         // Remove start flags from team data
  2002.         for (i=0;i<network_on;i++)
  2003.             Teams[i]-=2;
  2004.  
  2005.  
  2006.         // Now set Andy's data structures from the network variables
  2007.  
  2008.  
  2009. //        printf("\nTeam %d plays team %d\n",Team_A,Team_B);
  2010. //        printf("This node is %d\n",wConsoleNode);
  2011. //        printf("This node chose team %d, player %d\n",TeamChoice,PlayerChoice);
  2012. //        for (i=0;i<network_on;i++)
  2013. //            printf("Node %d plays team %d, player %d\n",i,Teams[i],Players[i]);
  2014. //        printf("Seed is %d\n",Seed);
  2015.         }
  2016.     else
  2017.         {
  2018.         End_Network_Game();    // Cleans up network stuff
  2019.         old_mf=1;
  2020.         return (-1);
  2021.         }
  2022.  
  2023.     // ...call the game...
  2024.  
  2025.     // ...whetever front end stuff comes after...
  2026.  
  2027.     return (0);
  2028. }
  2029.  
  2030. void crap()
  2031. {
  2032.     printf(" net %d  %d \n",*(int *)&users[0].inp_x,&users[0].inp_x);
  2033. }
  2034.